using Gateway.Common.Enums;
using Gateway.Common.Models;
using Gateway.Domain.Entities;
using Gateway.IApplication.BaseInput;
using Gateway.IApplication.Language;
using Gateway.IApplication.Language.Input;
using Gateway.IRepositories;
using Microsoft.EntityFrameworkCore;

namespace Gateway.Application;
/// <summary>
/// 
/// </summary>
public class LanguageApp : ILanguageApp
{
    private readonly IAppRepository<Language> _repository;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IAppRepository<LanguageExtensionCode> _codeRepository;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="repository"></param>
    /// <param name="unitOfWork"></param>
    /// <param name="codeRepository"></param>
    public LanguageApp(IAppRepository<Language> repository, IUnitOfWork unitOfWork,
        IAppRepository<LanguageExtensionCode> codeRepository)
    {
        _repository = repository;
        _unitOfWork = unitOfWork;
        _codeRepository = codeRepository;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> Set(CreateLanguageInput input)
    {
        //查找语言
        var entity =
            await _repository.FirstOrDefaultAsync(p => p.Deleted == BooleanStatusEnum.No && p.Lang.Equals(input.Lang));
        if (entity == null)
        {
            entity = new Language(lang: input.Lang, text: input.Text, build: input.Build,
                buildCommand: input.BuildCommand, exec: input.Exec, execCommand: input.ExecCommand,
                langType: input.LangType);
            await _repository.AddAsync(entity);
        }
        else
        {
            entity.Update(lang: input.Lang, text: input.Text, build: input.Build,
                buildCommand: input.BuildCommand, exec: input.Exec, execCommand: input.ExecCommand,
                langType: input.LangType);
            await _repository.UpdateAsync(entity);
        }

        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Remove(RemoveInput input)
    {
        var entity = await _repository.GetAsync(input.Id);
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.SetDeleted();
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Disable(DisableInput input)
    {
        var entity = await _repository.GetAsync(input.Id);
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.SetDisabled(input.Disable);
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> SetExtensionCode(LanguageExtensionCodeInput input)
    {
        var isAdd = string.IsNullOrEmpty(input.LanguageExtensionCodeId);
        var info = await _codeRepository.FirstOrDefaultAsync(x => x.Deleted == BooleanStatusEnum.No &&
            x.Name.Equals(input.Name)
            && x.LanguageId.Equals(input.LanguageId)
            && (isAdd || !x.Id.Equals(input.LanguageExtensionCodeId))
        );
        //查找是否有相同的 代码文件名称
        if (info != null)
            throw new MyException("存在相同的代码文件名称");
        if (isAdd)
        {
            var entity = new LanguageExtensionCode(input.Title, input.Name, input.Code, input.LanguageId);
            await _codeRepository.AddAsync(entity);
        }
        else
        {
            var entity = await _codeRepository.FirstOrDefaultAsync(p => p.Id.Equals(input.LanguageExtensionCodeId));
            if (entity != null)
            {
                entity.Update(input.Title, input.Name, input.Code, input.LanguageId);
                await _codeRepository.UpdateAsync(entity);
            }
        }

        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> RemoveCode(RemoveInput input)
    {
        var entity = await _codeRepository.FirstOrDefaultAsync(p => p.Id.Equals(input.Id));
        if (entity == null)
        {
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        }
        entity.SetDeleted();
        await _codeRepository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
}